#include "storage/storage.h"
#include <spdlog/spdlog.h>
#include <filesystem>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <ctime>

namespace hft {

bool Storage::init(const YAML::Node& config) {
    try {
        auto storage_config = config["storage"];
        auto market_data_config = storage_config["market_data"];
        auto trade_data_config = storage_config["trade_data"];

        config_.market_data_path = market_data_config["path"].as<std::string>();
        config_.trade_data_path = trade_data_config["path"].as<std::string>();
        config_.format = market_data_config["format"].as<std::string>();
        config_.compression = market_data_config["compression"].as<bool>();

        // 创建存储目录
        if (!createDirectories()) {
            return false;
        }

        // 打开文件
        if (!openFiles()) {
            return false;
        }

        // 写入CSV�?
        writeCSVHeaders();

        spdlog::info("Storage initialized successfully");
        return true;
    } catch (const std::exception& e) {
        spdlog::error("Failed to initialize storage: {}", e.what());
        return false;
    }
}

bool Storage::storeMarketData(const MarketDataMessage& data) {
    std::lock_guard<std::mutex> lock(mutex_);
    try {
        if (!files_.market_data_file || !files_.market_data_file->is_open()) {
            spdlog::error("Market data file is not open");
            return false;
        }

        // 转换为CSV格式
        std::stringstream ss;
        ss << data.symbol << ","
           << data.last_price << ","
           << data.volume << ","
           << data.turnover << ","
           << data.open_interest << ","
           << data.bid_price << ","
           << data.bid_volume << ","
           << data.ask_price << ","
           << data.ask_volume << ","
           << std::chrono::system_clock::to_time_t(data.timestamp);

        // 写入文件
        *files_.market_data_file << ss.str() << std::endl;
        files_.market_data_file->flush();

        return true;
    } catch (const std::exception& e) {
        spdlog::error("Failed to store market data: {}", e.what());
        return false;
    }
}

bool Storage::storeTrade(const Trade& trade) {
    std::lock_guard<std::mutex> lock(mutex_);
    try {
        if (!files_.trade_data_file || !files_.trade_data_file->is_open()) {
            spdlog::error("Trade data file is not open");
            return false;
        }

        // 转换为CSV格式
        std::stringstream ss;
        ss << trade.trade_id << ","
           << trade.order_id << ","
           << trade.symbol << ","
           << static_cast<int>(trade.direction) << ","
           << static_cast<int>(trade.offset) << ","
           << trade.price << ","
           << trade.volume << ","
           << std::chrono::system_clock::to_time_t(trade.timestamp);

        // 写入文件
        *files_.trade_data_file << ss.str() << std::endl;
        files_.trade_data_file->flush();

        return true;
    } catch (const std::exception& e) {
        spdlog::error("Failed to store trade data: {}", e.what());
        return false;
    }
}

bool Storage::storeOrder(const Order& order) {
    std::lock_guard<std::mutex> lock(mutex_);
    try {
        if (!files_.order_data_file || !files_.order_data_file->is_open()) {
            spdlog::error("Order data file is not open");
            return false;
        }

        // 转换为CSV格式
        std::stringstream ss;
        ss << order.order_id << ","
           << order.symbol << ","
           << static_cast<int>(order.direction) << ","
           << static_cast<int>(order.offset) << ","
           << static_cast<int>(order.type) << ","
           << order.price << ","
           << order.volume << ","
           << std::chrono::system_clock::to_time_t(order.timestamp);

        // 写入文件
        *files_.order_data_file << ss.str() << std::endl;
        files_.order_data_file->flush();

        return true;
    } catch (const std::exception& e) {
        spdlog::error("Failed to store order data: {}", e.what());
        return false;
    }
}

bool Storage::storePosition(const Position& position) {
    std::lock_guard<std::mutex> lock(mutex_);
    try {
        if (!files_.position_data_file || !files_.position_data_file->is_open()) {
            spdlog::error("Position data file is not open");
            return false;
        }

        // 转换为CSV格式
        std::stringstream ss;
        ss << position.symbol << ","
           << static_cast<int>(position.direction) << ","
           << position.volume << ","
           << position.open_price << ","
           << position.position_profit << ","
           << position.margin << ","
           << std::chrono::system_clock::to_time_t(position.timestamp);

        // 写入文件
        *files_.position_data_file << ss.str() << std::endl;
        files_.position_data_file->flush();

        return true;
    } catch (const std::exception& e) {
        spdlog::error("Failed to store position data: {}", e.what());
        return false;
    }
}

bool Storage::storeAccount(const Account& account) {
    std::lock_guard<std::mutex> lock(mutex_);
    try {
        if (!files_.account_data_file || !files_.account_data_file->is_open()) {
            spdlog::error("Account data file is not open");
            return false;
        }

        // 转换为CSV格式
        std::stringstream ss;
        ss << account.balance << ","
           << account.available << ","
           << account.margin << ","
           << account.commission << ","
           << account.frozen_margin << ","
           << account.frozen_commission << ","
           << std::chrono::system_clock::to_time_t(account.timestamp);

        // 写入文件
        *files_.account_data_file << ss.str() << std::endl;
        files_.account_data_file->flush();

        return true;
    } catch (const std::exception& e) {
        spdlog::error("Failed to store account data: {}", e.what());
        return false;
    }
}

bool Storage::createDirectories() {
    try {
        std::filesystem::create_directories(config_.market_data_path);
        std::filesystem::create_directories(config_.trade_data_path);
        return true;
    } catch (const std::exception& e) {
        spdlog::error("Failed to create storage directories: {}", e.what());
        return false;
    }
}

bool Storage::openFiles() {
    try {
        std::string date_str = getCurrentDateString();
        std::string market_data_file = config_.market_data_path + "/market_data_" + date_str + ".csv";
        std::string trade_data_file = config_.trade_data_path + "/trade_data_" + date_str + ".csv";
        std::string order_data_file = config_.trade_data_path + "/order_data_" + date_str + ".csv";
        std::string position_data_file = config_.trade_data_path + "/position_data_" + date_str + ".csv";
        std::string account_data_file = config_.trade_data_path + "/account_data_" + date_str + ".csv";

        files_.market_data_file = std::make_unique<std::ofstream>(market_data_file, std::ios::app);
        files_.trade_data_file = std::make_unique<std::ofstream>(trade_data_file, std::ios::app);
        files_.order_data_file = std::make_unique<std::ofstream>(order_data_file, std::ios::app);
        files_.position_data_file = std::make_unique<std::ofstream>(position_data_file, std::ios::app);
        files_.account_data_file = std::make_unique<std::ofstream>(account_data_file, std::ios::app);

        return true;
    } catch (const std::exception& e) {
        spdlog::error("Failed to open storage files: {}", e.what());
        return false;
    }
}

void Storage::closeFiles() {
    files_.market_data_file.reset();
    files_.trade_data_file.reset();
    files_.order_data_file.reset();
    files_.position_data_file.reset();
    files_.account_data_file.reset();
}

void Storage::writeCSVHeaders() {
    // 市场数据CSV�?
    *files_.market_data_file << "symbol,last_price,volume,turnover,open_interest,"
                            << "bid_price,bid_volume,ask_price,ask_volume,timestamp" << std::endl;

    // 成交数据CSV�?
    *files_.trade_data_file << "trade_id,order_id,symbol,direction,offset,"
                           << "price,volume,timestamp" << std::endl;

    // 订单数据CSV�?
    *files_.order_data_file << "order_id,symbol,direction,offset,type,"
                           << "price,volume,timestamp" << std::endl;

    // 持仓数据CSV�?
    *files_.position_data_file << "symbol,direction,volume,open_price,"
                              << "position_profit,margin,timestamp" << std::endl;

    // 账户数据CSV�?
    *files_.account_data_file << "balance,available,margin,commission,"
                             << "frozen_margin,frozen_commission,timestamp" << std::endl;
}

std::string Storage::getCurrentDateString() {
    auto now = std::chrono::system_clock::now();
    auto time = std::chrono::system_clock::to_time_t(now);
    std::stringstream ss;
    ss << std::put_time(std::localtime(&time), "%Y%m%d");
    return ss.str();
}

} // namespace hft 
